package ObjectOriented;

/**
 * 静态字段
    1. 实例字段在每个实例中都有自己的一个独立“空间”，但是静态字段只有一个共享“空间”
    2. 对于静态字段，无论修改哪个实例的静态字段，效果都是一样的：所有实例的静态字段都被修改了，原因是静态字段并不属于实例：
    3. 不推荐用实例变量.静态字段去访问静态字段,实例对象能访问静态字段只是因为编译器可以根据实例类型自动转换为类名.静态字段来访问静态对象。
    4. 推荐用类名来访问静态字段。 Person.number

  静态方法: 用static修饰的方法称为静态方法。
    1、调用实例方法必须通过一个实例变量，而调用静态方法则不需要实例变量，通过类名就可以调用。
    2、因为静态方法属于class而不属于实例，因此，静态方法内部，无法访问this变量，也无法访问实例字段，它只能访问静态字段。

  接口的静态字段和静态方法
    1、接口的静态字段是可以有的，而且是public static final类型的，不写也是这样的
    2、接口的静态方法是可以有的，而且是public类型的，不写也是这样的
    3、接口的静态方法只能访问接口的静态字段，不能访问实例字段和实例方法
*/

class Person {
  public String name;
  public int age;
  
  public static int number;

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
  public static void run() {
    System.out.println("run");
  }
}

interface Hello {
  public static final int number = 100;
  public static void run() {
    System.out.println("Hello.run");
  }
}

class Student implements Hello {
  public String name;
  public int age;
  
  public Student(String name, int age) {
    this.name = name;
    this.age = age;
  }
  public static void run() {
    System.out.println("Hello.run");
  }
}
public class StaticField {
  public static void main(String[] args) {
    Student s = new Student("Alice", 20);
    System.out.println(Student.number); // 100
    System.out.println(Hello.number); // 100
    Student.run(); // Hello.run
  }
  // public static void main(String[] args) {
  //   Person p1 = new Person("Tom", 20);
  //   Person p2 = new Person("Jerry", 22);

  //   p1.number = 100;
  //   p2.number = 200;

  //   System.out.println(p1.number); // 200
  //   System.out.println(p2.number); // 200
  //   Person.number = 300;
    
  //   System.out.println(p1.age);  
  //   System.out.println(p2.age);  

  //   System.out.println(Person.number); // 200

  //   Person.run();
  //   // 不推荐以下调用方式
  //   p1.run();
  // }
}
